﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using RuoVea.ExConfig;
using RuoVea.ExSugar;
using SqlSugar;
using RuoVea.OmiApi.Article.Entitys;
using RuoVea.OmiApi.Article.Service;

namespace RuoVea.OmiApi.Article;

/// <summary>
/// 注入扩展
/// </summary>
public static class ServiceCollectionExtensions
{
    /// <summary>
    /// 文章管理
    /// </summary>
    /// <param name="services"></param>
    /// <param name="serviceLifetime">Scoped</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiArticleSetup(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        services.Configure<DbInitConfig>(AppSettings.Configuration.GetSection("DbInitConfig"));
        return DI(services, null, serviceLifetime);
    }

    /// <summary>
    /// 文章管理
    /// </summary>
    /// <param name="services"></param>
    /// <param name="config"></param>
    /// <param name="serviceLifetime">Scoped</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiArticleSetup(this IServiceCollection services, IConfiguration config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (config == null) throw new ArgumentNullException(nameof(config));
        services.Configure<DbInitConfig>(config);
        DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
        return DI(services, dbInitConfig, serviceLifetime);
    }

    /// <summary>
    /// 文章管理
    /// </summary>
    /// <param name="services"></param>
    /// <param name="config"></param>
    /// <param name="serviceLifetime">Scoped</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiArticleSetup(this IServiceCollection services, Action<DbInitConfig> config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (config == null) throw new ArgumentNullException(nameof(config));
        services.Configure(config);
        DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
        return DI(services, dbInitConfig, serviceLifetime);
    }

    #region DI
    private static IServiceCollection DI(IServiceCollection services, DbInitConfig dbInitConfig, ServiceLifetime serviceLifetime)
    {
        switch (serviceLifetime)
        {
            case ServiceLifetime.Scoped:
                services.AddScoped<ArticleService>();
                services.AddScoped<CategoryService>();
                services.AddScoped<CommentService>();
                services.AddScoped<FavoriteService>();
                services.AddScoped<LikeService>();
                services.AddScoped<TagService>();
                services.AddScoped<CategoryArticleService>(); 
                services.AddScoped<ArticleTagService>(); 
                break;
            case ServiceLifetime.Singleton:
                services.AddSingleton<ArticleService>();
                services.AddSingleton<CategoryService>();
                services.AddSingleton<CommentService>();
                services.AddSingleton<FavoriteService>();
                services.AddSingleton<LikeService>();
                services.AddSingleton<TagService>();
                services.AddSingleton<CategoryArticleService>();
                services.AddSingleton<ArticleTagService>();
                break;
            case ServiceLifetime.Transient:
                services.AddTransient<ArticleService>();
                services.AddTransient<CategoryService>();
                services.AddTransient<CommentService>();
                services.AddTransient<FavoriteService>();
                services.AddTransient<LikeService>();
                services.AddTransient<TagService>();
                services.AddTransient<CategoryArticleService>();
                services.AddTransient<ArticleTagService>();
                break;
        }
        return services;
    }
    #endregion

    /// <summary>
    /// 文章管理 - 初始化数据库/初始化种子数据
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public static IServiceCollection AddArticleInitSetup(this IServiceCollection services)
    {
        Task.Run(() =>
        {
            DbInitConfig config = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
            var _thisRepository = services.BuildServiceProvider().GetRequiredService<ISqlSugarClient>();
            if (config.InitTable && _thisRepository != null)
            {
                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtArticle), false) || _thisRepository.DbMaintenance.IsAnyTable("art_article", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtArticle>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtComment), false) || _thisRepository.DbMaintenance.IsAnyTable("art_article_comment", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtComment>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtFavorite), false) || _thisRepository.DbMaintenance.IsAnyTable("art_article_favorite", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtFavorite>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtLike), false) || _thisRepository.DbMaintenance.IsAnyTable("art_article_like", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtLike>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtSeo), false) || _thisRepository.DbMaintenance.IsAnyTable("art_article_seo", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtSeo>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtArticleTag), false) || _thisRepository.DbMaintenance.IsAnyTable("art_article_tag", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtArticleTag>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtCategory), false) || _thisRepository.DbMaintenance.IsAnyTable("art_category", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtCategory>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtCategoryArticle), false) || _thisRepository.DbMaintenance.IsAnyTable("art_category_article", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtCategoryArticle>();

                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(ArtTag), false) || _thisRepository.DbMaintenance.IsAnyTable("art_tag", false)) { }
                else
                    _thisRepository.CodeFirst.InitTables<ArtTag>();
            }
        });
        return services;
    }
}
